home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume24 / zsh2.1 / part05 < prev    next >
Encoding:
Text File  |  1991-10-24  |  48.2 KB  |  2,406 lines

  1. Newsgroups: comp.sources.misc
  2. From: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
  3. Subject:  v24i005:  zsh2.1 - The Z shell, Part05/19
  4. Message-ID: <1991Oct24.190820.25645@sparky.imd.sterling.com>
  5. X-Md4-Signature: 5e7ea05d892fb6c05ee120f1110c3b0a
  6. Date: Thu, 24 Oct 1991 19:08:20 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
  10. Posting-number: Volume 24, Issue 5
  11. Archive-name: zsh2.1/part05
  12. Environment: BSD
  13. Supersedes: zsh2.00: Volume 18, Issue 84-98
  14.  
  15. #!/bin/sh
  16. # this is zshar.05 (part 5 of zsh2.1.0)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file zsh2.1/src/builtin.c continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 5; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping zsh2.1/src/builtin.c'
  34. else
  35. echo 'x - continuing file zsh2.1/src/builtin.c'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'zsh2.1/src/builtin.c' &&
  37. X        }
  38. X    return 0;
  39. X}
  40. X
  41. Xstatic char *recs[] = {
  42. X    "cputime","filesize","datasize","stacksize","coredumpsize",
  43. X    "resident","descriptors"
  44. X    };
  45. X
  46. Xint bin_limit(nam,argv,ops,func) /**/
  47. Xchar *nam;char **argv;char *ops;int func;
  48. X{
  49. X#ifndef RLIM_INFINITY
  50. X    zerrnam(nam,"not available on this system",NULL,0);
  51. X    return 1;
  52. X#else
  53. Xchar *s;
  54. Xint hard = ops['h'],t0,lim;
  55. Xlong val;
  56. X
  57. X    if (ops['s'])
  58. X        {
  59. X        if (*argv)
  60. X            zerrnam(nam,"arguments after -s ignored",NULL,0);
  61. X        for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
  62. X            if (setrlimit(t0,limits+t0) < 0)
  63. X                zerrnam(nam,"setrlimit failed: %e",NULL,errno);
  64. X        return 0;
  65. X        }
  66. X    if (!*argv)
  67. X        {
  68. X        showlimits(hard,-1);
  69. X        return 0;
  70. X        }
  71. X    while (s = *argv++)
  72. X        {
  73. X        for (lim = -1, t0 = 0; t0 != RLIM_NLIMITS; t0++)
  74. X            if (!strncmp(recs[t0],s,strlen(s)))
  75. X                {
  76. X                if (lim != -1)
  77. X                    lim = -2;
  78. X                else
  79. X                    lim = t0;
  80. X                }
  81. X        if (lim < 0)
  82. X            {
  83. X            zerrnam("limit",
  84. X                (lim == -2) ? "ambiguous resource specification: %s"
  85. X                                : "no such resource: %s",s,0);
  86. X            return 1;
  87. X            }
  88. X        if (!(s = *argv++))
  89. X            {
  90. X            showlimits(hard,lim);
  91. X            return 0;
  92. X            }
  93. X        if (!lim)
  94. X            {
  95. X            val = zstrtol(s,&s,10);
  96. X            if (*s)
  97. X                if ((*s == 'h' || *s == 'H') && !s[1])
  98. X                    val *= 3600L;
  99. X                else if ((*s == 'm' || *s == 'M') && !s[1])
  100. X                    val *= 60L;
  101. X                else if (*s == ':')
  102. X                    val = val*60+zstrtol(s+1,&s,10);
  103. X                else
  104. X                    {
  105. X                    zerrnam("limit","unknown scaling factor: %s",s,0);
  106. X                    return 1;
  107. X                    }
  108. X            }
  109. X#ifdef RLIMIT_NOFILE
  110. X        else if (lim == RLIMIT_NOFILE)
  111. X            val = zstrtol(s,&s,10);
  112. X#endif
  113. X        else
  114. X            {
  115. X            val = zstrtol(s,&s,10);
  116. X            if (!*s || ((*s == 'k' || *s == 'K') && !s[1]))
  117. X                val *= 1024L;
  118. X            else if ((*s == 'M' || *s == 'm') && !s[1])
  119. X                val *= 1024L*1024;
  120. X            else
  121. X                {
  122. X                zerrnam("limit","unknown scaling factor: %s",s,0);
  123. X                return 1;
  124. X                }
  125. X            }
  126. X        if (hard)
  127. X            if (val > limits[lim].rlim_max && geteuid())
  128. X                {
  129. X                zerrnam("limit","can't raise hard limits",NULL,0);
  130. X                return 1;
  131. X                }
  132. X            else
  133. X                {
  134. X                limits[lim].rlim_max = val;
  135. X                if (limits[lim].rlim_max < limits[lim].rlim_cur)
  136. X                    limits[lim].rlim_cur = limits[lim].rlim_max;
  137. X                }
  138. X        else
  139. X            if (val > limits[lim].rlim_max)
  140. X                {
  141. X                zerrnam("limit","limit exceeds hard limit",NULL,0);
  142. X                return 1;
  143. X                }
  144. X            else
  145. X                limits[lim].rlim_cur = val;
  146. X        }
  147. X    return 0;
  148. X#endif
  149. X}
  150. X
  151. Xint bin_unlimit(nam,argv,ops,func) /**/
  152. Xchar *nam;char **argv;char *ops;int func;
  153. X{
  154. X#ifndef RLIM_INFINITY
  155. X    zerrnam(nam,"not available on this system",NULL,0);
  156. X    return 1;
  157. X#else
  158. Xint hard = ops['h'],t0,lim;
  159. X
  160. X    if (hard && geteuid())
  161. X        {
  162. X        zerrnam(nam,"can't remove hard limits",NULL,0);
  163. X        return 1;
  164. X        }
  165. X    if (!*argv)
  166. X        {
  167. X        for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
  168. X            {
  169. X            if (hard)
  170. X                limits[t0].rlim_max = RLIM_INFINITY;
  171. X            else
  172. X                limits[t0].rlim_cur = limits[t0].rlim_max;
  173. X            }
  174. X        return 0;
  175. X        }
  176. X    for (; *argv; argv++)
  177. X        {
  178. X        for (lim = -1, t0 = 0; t0 != RLIM_NLIMITS; t0++)
  179. X            if (!strncmp(recs[t0],*argv,strlen(*argv)))
  180. X                {
  181. X                if (lim != -1)
  182. X                    lim = -2;
  183. X                else
  184. X                    lim = t0;
  185. X                }
  186. X        if (lim < 0)
  187. X            {
  188. X            zerrnam(nam,
  189. X                (lim == -2) ? "ambiguous resource specification: %s"
  190. X                                : "no such resource: %s",*argv,0);
  191. X            return 1;
  192. X            }
  193. X        if (hard)
  194. X            limits[lim].rlim_max = RLIM_INFINITY;
  195. X        else
  196. X            limits[lim].rlim_cur = limits[lim].rlim_max;
  197. X        }
  198. X    return 0;
  199. X#endif
  200. X}
  201. X
  202. Xvoid showlimits(hard,lim) /**/
  203. Xint hard;int lim;
  204. X{
  205. Xint t0;
  206. Xlong val;
  207. X
  208. X#ifdef RLIM_INFINITY
  209. X    for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
  210. X        if (t0 == lim || lim == -1)
  211. X            {
  212. X            printf("%-16s",recs[t0]);
  213. X            val = (hard) ? limits[t0].rlim_max : limits[t0].rlim_cur;
  214. X            if (val == RLIM_INFINITY)
  215. X                printf("unlimited\n");
  216. X            else if (!t0)
  217. X                printf("%d:%02d:%02d\n",(int) (val/3600),
  218. X                    (int) (val/60) % 60,(int) (val % 60));
  219. X#ifdef RLIMIT_NOFILE
  220. X            else if (t0 == RLIMIT_NOFILE)
  221. X                printf("%d\n",(int) val);
  222. X#endif
  223. X            else if (val >= 1024L*1024L)
  224. X                printf("%ldMb\n",val/(1024L*1024L));
  225. X            else
  226. X                printf("%ldKb\n",val/1024L);
  227. X            }
  228. X#endif
  229. X}
  230. X
  231. Xint bin_sched(nam,argv,ops,func) /**/
  232. Xchar *nam;char **argv;char *ops;int func;
  233. X{
  234. Xchar *s = *argv++;
  235. Xtime_t t;
  236. Xlong h,m;
  237. Xstruct tm *tm;
  238. Xstruct schedcmd *sch,*sch2,*schl;
  239. Xint t0;
  240. X
  241. X    if (s && *s == '-')
  242. X        {
  243. X        t0 = atoi(s+1);
  244. X
  245. X        if (!t0)
  246. X            {
  247. X            zerrnam("sched","usage for delete: sched -<item#>.",NULL,0);
  248. X            return 1;
  249. X            }
  250. X        for (schl = (struct schedcmd *) &schedcmds, sch = schedcmds, t0--;
  251. X                sch && t0; sch = (schl = sch)->next, t0--);
  252. X        if (!sch)
  253. X            {
  254. X            zerrnam("sched","not that many entries",NULL,0);
  255. X            return 1;
  256. X            }
  257. X        schl->next = sch->next;
  258. X        free(sch->cmd);
  259. X        free(sch);
  260. X        return 0;
  261. X        }
  262. X    if (!s)
  263. X        {
  264. X        char tbuf[40];
  265. X
  266. X        for (t0 = 1, sch = schedcmds; sch; sch = sch->next,t0++)
  267. X            {
  268. X            t = sch->time;
  269. X            tm = localtime(&t);
  270. X            ztrftime(tbuf,20,"%a %b %e %k:%M:%S",tm);
  271. X            printf("%3d %s %s\n",t0,tbuf,sch->cmd);
  272. X            }
  273. X        return 0;
  274. X        }
  275. X    else if (!*argv)
  276. X        {
  277. X        zerrnam("sched","not enough arguments",NULL,0);
  278. X        return 1;
  279. X        }
  280. X    if (*s == '+')
  281. X        {
  282. X        h = zstrtol(s+1,&s,10);
  283. X        if (*s != ':')
  284. X            {
  285. X            zerrnam("sched","bad time specifier",NULL,0);
  286. X            return 1;
  287. X            }
  288. X        m = zstrtol(s+1,&s,10);
  289. X        if (*s)
  290. X            {
  291. X            zerrnam("sched","bad time specifier",NULL,0);
  292. X            return 1;
  293. X            }
  294. X        t = time(NULL)+h*3600+m*60;
  295. X        }
  296. X    else
  297. X        {
  298. X        h = zstrtol(s,&s,10);
  299. X        if (*s != ':')
  300. X            {
  301. X            zerrnam("sched","bad time specifier",NULL,0);
  302. X            return 1;
  303. X            }
  304. X        m = zstrtol(s+1,&s,10);
  305. X        if (*s && *s != 'a' && *s != 'p')
  306. X            {
  307. X            zerrnam("sched","bad time specifier",NULL,0);
  308. X            return 1;
  309. X            }
  310. X        t = time(NULL);
  311. X        tm = localtime(&t);
  312. X        t -= tm->tm_sec+tm->tm_min*60+tm->tm_hour*3600;
  313. X        if (*s == 'p')
  314. X            h += 12;
  315. X        t += h*3600+m*60;
  316. X        if (t < time(NULL))
  317. X            t += 3600*24;
  318. X        }
  319. X    sch = zcalloc(sizeof *sch);
  320. X    sch->time = t;
  321. X    sch->cmd = spacejoin(argv);
  322. X    sch->next = NULL;
  323. X    for (sch2 = (struct schedcmd *) &schedcmds; sch2->next; sch2 = sch2->next);
  324. X    sch2->next = sch;
  325. X    return 0;
  326. X}
  327. X
  328. Xint bin_eval(nam,argv,ops,func) /**/
  329. Xchar *nam;char **argv;char *ops;int func;
  330. X{
  331. Xchar *s = spacejoin(argv);
  332. XList list;
  333. X
  334. X    hungets(s);
  335. X    free(s);
  336. X    strinbeg();
  337. X    if (!(list = parse_list()))
  338. X        {
  339. X        hflush();
  340. X        strinend();
  341. X        return 1;
  342. X        }
  343. X    strinend();
  344. X    runlist(list);
  345. X    return lastval;
  346. X}
  347. X
  348. X/* get the history event associated with s */
  349. X
  350. Xint fcgetcomm(s) /**/
  351. Xchar *s;
  352. X{
  353. Xint cmd;
  354. X
  355. X    if (cmd = atoi(s))
  356. X        {
  357. X        if (cmd < 0)
  358. X            cmd = curhist+cmd+1;
  359. X        return cmd;
  360. X        }
  361. X    cmd = hcomsearch(s);
  362. X    if (cmd == -1)
  363. X        zerrnam("fc","event not found: %s",s,0);
  364. X    return cmd;
  365. X}
  366. X
  367. X/* perform old=new substituion */
  368. X
  369. Xint fcsubs(sp,sub) /**/
  370. Xchar **sp;struct asgment *sub;
  371. X{
  372. Xchar *s1,*s2,*s3,*s4,*s = *sp,*s5;
  373. Xint subbed = 0;
  374. X
  375. X    while (sub)
  376. X        {
  377. X        s1 = sub->name;
  378. X        s2 = sub->value;
  379. X        sub = sub->next;
  380. X        s5 = s;
  381. X        while (s3 = (char *) ztrstr(s5,s1))
  382. X            {
  383. X            s4 = alloc(1+(s3-s)+strlen(s2)+strlen(s3+strlen(s1)));
  384. X            ztrncpy(s4,s,s3-s);
  385. X            strcat(s4,s2);
  386. X            s5 = s4+strlen(s4);
  387. X            strcat(s4,s3+strlen(s1));
  388. X            s = s4;
  389. X            subbed = 1;
  390. X            }
  391. X        }
  392. X    *sp = s;
  393. X    return subbed;
  394. X}
  395. X
  396. X/* print a series of history events to a file */
  397. X
  398. Xint fclist(f,n,r,first,last,subs) /**/
  399. XFILE *f;int n;int r;int first;int last;struct asgment *subs;
  400. X{
  401. Xint done = 0,ct;
  402. XLknode node;
  403. Xchar *s;
  404. X
  405. X    if (!subs)
  406. X        done = 1;
  407. X    last -= first;
  408. X    first -= firsthist;
  409. X    if (r)
  410. X        first += last;
  411. X    for (node = firstnode(histlist),ct = first; ct && node;
  412. X        incnode(node), ct--);
  413. X    first += firsthist;
  414. X    while (last-- >= 0)
  415. X        {
  416. X        if (!node)
  417. X            {
  418. X            zerrnam("fc","no such event: %d",NULL,first);
  419. X            return 1;
  420. X            }
  421. X        s = makehstr(getdata(node));
  422. X        done |= fcsubs(&s,subs);
  423. X        if (n)
  424. X            fprintf(f,"%5d  ",first);
  425. X        if (f == stdout)
  426. X            {
  427. X            niceprintf(s,f);
  428. X            putc('\n',f);
  429. X            }
  430. X        else
  431. X            fprintf(f,"%s\n",s);
  432. X        node = (r) ? prevnode(node) : nextnode(node);
  433. X        (r) ? first-- : first++;
  434. X        }
  435. X    if (f != stdout)
  436. X        fclose(f);
  437. X    if (!done)
  438. X        {
  439. X        zerrnam("fc","no substitutions performed",NULL,0);
  440. X        return 1;
  441. X        }
  442. X    return 0;
  443. X}
  444. X
  445. Xint fcedit(ename,fn) /**/
  446. Xchar *ename;char *fn;
  447. X{
  448. X    if (!strcmp(ename,"-"))
  449. X        return 1;
  450. X    return !zyztem(ename,fn);
  451. X}
  452. X
  453. X/* fc, history, r */
  454. X
  455. Xint bin_fc(nam,argv,ops,func) /**/
  456. Xchar *nam;char **argv;char *ops;int func;
  457. X{
  458. Xint first = -1,last = -1,retval,minflag = 0;
  459. Xchar *s;
  460. Xstruct asgment *asgf = NULL,*asgl = NULL;
  461. X
  462. X    if (!interact)
  463. X        {
  464. X        zerrnam(nam,"not interactive shell",NULL,0);
  465. X        return 1;
  466. X        }
  467. X    if (!(ops['l'] && unset(HISTNOSTORE)))
  468. X        remhist();
  469. X    if (ops['R'])
  470. X        {
  471. X        readhistfile(*argv ? *argv : getsparam("HISTFILE"),1);
  472. X        return 0;
  473. X        }
  474. X    if (ops['W'])
  475. X        {
  476. X        savehistfile(*argv ? *argv : getsparam("HISTFILE"),1);
  477. X        return 0;
  478. X        }
  479. X    while (*argv && equalsplit(*argv,&s))
  480. X        {
  481. X        struct asgment *a = (struct asgment *) alloc(sizeof *a);
  482. X
  483. X        if (!asgf)
  484. X            asgf = asgl = a;
  485. X        else
  486. X            {
  487. X            asgl->next = a;
  488. X            asgl = a;
  489. X            }
  490. X        a->name = *argv;
  491. X        a->value = s;
  492. X        argv++;
  493. X        }
  494. X    if (*argv)
  495. X        {
  496. X        minflag = **argv == '-';
  497. X        first = fcgetcomm(*argv);
  498. X        if (first == -1)
  499. X            return 1;
  500. X        argv++;
  501. X        }
  502. X    if (*argv)
  503. X        {
  504. X        last = fcgetcomm(*argv);
  505. X        if (last == -1)
  506. X            return 1;
  507. X        argv++;
  508. X        }
  509. X    if (*argv)
  510. X        {
  511. X        zerrnam("fc","too many arguments",NULL,0);
  512. X        return 1;
  513. X        }
  514. X    if (first == -1)
  515. X        {
  516. X        first = (ops['l']) ? curhist-16 : curhist;
  517. X        if (last == -1)
  518. X            last = (ops['l']) ? curhist : first;
  519. X        }
  520. X    if (first < firsthist)
  521. X        first = firsthist;
  522. X    if (last == -1)
  523. X        last = (minflag) ? curhist : first;
  524. X    if (ops['l'])
  525. X        retval = fclist(stdout,!ops['n'],ops['r'],first,last,asgf);
  526. X    else
  527. X        {
  528. X        FILE *out;
  529. X        char *fil = gettemp();
  530. X
  531. X        out = fopen(fil,"w");
  532. X        if (!out)
  533. X            zerrnam("fc","can't open temp file: %e",NULL,errno);
  534. X        else
  535. X            {
  536. X            retval = 1;
  537. X            if (!fclist(out,0,ops['r'],first,last,asgf))
  538. X                if (fcedit(auxdata ? auxdata : fceditparam,fil))
  539. X                    if (stuff(fil))
  540. X                        zerrnam("fc","%e: %s",s,errno);
  541. X                    else
  542. X                        retval = 0;
  543. X            }
  544. X        unlink(fil);
  545. X        }
  546. X    return retval;
  547. X}
  548. X
  549. Xint bin_suspend(name,argv,ops,func) /**/
  550. Xchar *name;char **argv;char *ops;int func;
  551. X{
  552. X    if (islogin && !ops['f'])
  553. X        {
  554. X        zerrnam(name,"can't suspend login shell",NULL,0);
  555. X        return 1;
  556. X        }
  557. X    if (jobbing)
  558. X        signal(SIGTSTP,SIG_DFL);
  559. X    kill(0,SIGTSTP);
  560. X    if (jobbing)
  561. X        signal(SIGTSTP,SIG_IGN);
  562. X    return 0;
  563. X}
  564. X
  565. Xint bin_alias(name,argv,ops,func) /**/
  566. Xchar *name;char **argv;char *ops;int func;
  567. X{
  568. Xstruct alias *an;
  569. Xstruct asgment *asg;
  570. Xint incm = !(ops['a'] || ops['g']),ret = 0;
  571. X
  572. X    showflag = !incm;
  573. X    if (!*argv)
  574. X        listhtable(aliastab,(HFunc) printalias);
  575. X    else while (asg = getasg(*argv++))
  576. X        {
  577. X        if (asg->value)
  578. X            addhnode(ztrdup(asg->name),mkanode(ztrdup(asg->value),incm),
  579. X                aliastab,freeanode);
  580. X        else if (an = (Alias) gethnode(asg->name,aliastab))
  581. X            printalias(asg->name,an);
  582. X        else
  583. X            ret = 1;
  584. X        }
  585. X    return ret;
  586. X}
  587. X
  588. X/* print an alias; used with listhtable */
  589. X
  590. Xvoid printalias(s,a) /**/
  591. Xchar *s;struct alias *a;
  592. X{
  593. X    if (a->cmd >= 0 && !(showflag && a->cmd))
  594. X        printf("%s=%s\n",s,a->text);
  595. X}
  596. X
  597. X/* print a param; used with listhtable */
  598. X
  599. Xvoid printparam(s,p) /**/
  600. Xchar *s;Param p;
  601. X{
  602. X    if (showflag && !(p->flags & showflag))
  603. X        return;
  604. X    if (!showflag)
  605. X        {
  606. X        int fgs = p->flags;
  607. X
  608. X        if (fgs & PMFLAG_i) printf("integer ");
  609. X        if (fgs & PMFLAG_A) printf("array ");
  610. X        if (fgs & PMFLAG_L) printf("left justified %d ",p->ct);
  611. X        if (fgs & PMFLAG_R) printf("right justified %d ",p->ct);
  612. X        if (fgs & PMFLAG_Z) printf("zero filled %d ",p->ct);
  613. X        if (fgs & PMFLAG_l) printf("lowercase ");
  614. X        if (fgs & PMFLAG_u) printf("uppercase ");
  615. X        if (fgs & PMFLAG_r) printf("readonly ");
  616. X        if (fgs & PMFLAG_t) printf("tagged ");
  617. X        if (fgs & PMFLAG_x) printf("exported ");
  618. X        }
  619. X    if (showflag2)
  620. X        printf("%s\n",s);
  621. X    else
  622. X        {
  623. X        char *t,**u;
  624. X
  625. X        printf("%s=",s);
  626. X        switch (p->flags & PMTYPE)
  627. X            {
  628. X            case PMFLAG_s:
  629. X                if (p->gets.cfn && (t = p->gets.cfn(p)))
  630. X                    puts(t);
  631. X                else
  632. X                    putchar('\n');
  633. X                break;
  634. X            case PMFLAG_i: printf("%ld\n",p->gets.ifn(p)); break;
  635. X            case PMFLAG_A:
  636. X                putchar('(');
  637. X                u = p->gets.afn(p);
  638. X                if (!*u)
  639. X                    printf(")\n");
  640. X                else
  641. X                    {
  642. X                    while (u[1])
  643. X                        printf("%s ",*u++);
  644. X                    printf("%s)\n",*u);
  645. X                    }
  646. X                break;
  647. X            }
  648. X        }
  649. X}
  650. X
  651. X/* autoload, declare, export, functions, integer, local, readonly, typeset */
  652. X
  653. Xint bin_typeset(name,argv,ops,func) /**/
  654. Xchar *name;char **argv;char *ops;int func;
  655. X{
  656. Xint on = 0,off = 0,roff,bit = 1,retcode = 0;
  657. Xchar *optstr = "LRZilurtx";
  658. Xstruct param *pm;
  659. Xstruct asgment *asg;
  660. X
  661. X    for (; *optstr; optstr++,bit <<= 1)
  662. X        if (ops[*optstr] == 1)
  663. X            on |= bit;
  664. X        else if (ops[*optstr] == 2)
  665. X            off |= bit;
  666. X    roff = off;
  667. X    if (ops['f'])
  668. X        {
  669. X        on &= PMFLAG_t|PMFLAG_u;
  670. X        off &= PMFLAG_t|PMFLAG_u;
  671. X        showflag = (ops['f'] == 1);
  672. X        if (ops['@'] && (off || (on & ~(PMFLAG_u|PMFLAG_t))))
  673. X            {
  674. X            zerrnam(name,"invalid option(s)",NULL,0);
  675. X            return 1;
  676. X            }
  677. X        showflag2 = 0;
  678. X        if (!*argv)
  679. X            {
  680. X            showflag2 = off|on;
  681. X            listhtable(cmdnamtab,(HFunc) pshfunc);
  682. X            }
  683. X        else for (; *argv; argv++)
  684. X            {
  685. X            Cmdnam cc;
  686. X
  687. X            if ((cc = (Cmdnam) gethnode(*argv,cmdnamtab)) && cc->type == SHFUNC)
  688. X                if (on)
  689. X                    cc->flags |= on;
  690. X                else
  691. X                    pshfunc(*argv,cc);
  692. X            else if (on & PMFLAG_u)
  693. X                {
  694. X                cc = (Cmdnam) zcalloc(sizeof *cc);
  695. X                cc->type = SHFUNC;
  696. X                cc->flags = on;
  697. X                addhnode(ztrdup(*argv),cc,cmdnamtab,freecmdnam);
  698. X                }
  699. X            else
  700. X                retcode = 1;
  701. X            }
  702. X        return retcode;
  703. X        }
  704. X    if (on & PMFLAG_L)
  705. X        off |= PMFLAG_R;
  706. X    if (on & PMFLAG_R)
  707. X        off |= PMFLAG_L;
  708. X    if (on & PMFLAG_u)
  709. X        off |= PMFLAG_l;
  710. X    if (on & PMFLAG_l)
  711. X        off |= PMFLAG_u;
  712. X    on &= ~off;
  713. X    if (!*argv)
  714. X        {
  715. X        showflag = on|off;
  716. X        showflag2 = roff;
  717. X        listhtable(paramtab,(HFunc) printparam);
  718. X        }
  719. X    else while (asg = getasg(*argv++))
  720. X        {
  721. X        if (asg->value && *asg->value == '~') {
  722. X            *asg->value = Tilde;
  723. X            singsub(&asg->value);
  724. X        }
  725. X        pm = (Param) gethnode(asg->name,paramtab);
  726. X        if (pm)
  727. X            {
  728. X            if (!on && !roff && !asg->value)
  729. X                {
  730. X                printparam(asg->name,pm);
  731. X                continue;
  732. X                }
  733. X            pm->flags = (pm->flags | on) & ~off;
  734. X            if ((on & (PMFLAG_L | PMFLAG_R | PMFLAG_Z | PMFLAG_i)) 
  735. X                    && (pmtype(pm) != PMFLAG_A))
  736. X                pm->ct = auxlen;
  737. X            if (pmtype(pm) != PMFLAG_A)
  738. X                {
  739. X                if (pm->flags & PMFLAG_x)
  740. X                    {
  741. X                    if (!pm->env)
  742. X                        pm->env = addenv(asg->name,
  743. X                            (asg->value) ? asg->value : getsparam(asg->name));
  744. X                    }
  745. X                else if (pm->env)
  746. X                    delenv(pm->env);
  747. X                if (asg->value)
  748. X                    setsparam(asg->name,ztrdup(asg->value));
  749. X                }
  750. X            }
  751. X        else
  752. X            {
  753. X            if (locallist && !(on & PMFLAG_x))
  754. X                {
  755. X                permalloc();
  756. X                addnode(locallist,ztrdup(asg->name));
  757. X                heapalloc();
  758. X                }
  759. X            createparam(ztrdup(asg->name),
  760. X                ztrdup((asg->value) ? asg->value : ""),on);
  761. X            pm = (Param) gethnode(asg->name,paramtab);
  762. X            pm->ct = auxlen;
  763. X            }
  764. X        }
  765. X    return 0;
  766. X}
  767. X
  768. X/* print s with escape sequences */
  769. X
  770. Xint escputs(s) /**/
  771. Xchar *s;
  772. X{
  773. Xint nnl = 0;
  774. X
  775. X    for (; *s; s++)
  776. X        if (*s == '\\' && s[1])
  777. X            switch (*++s)
  778. X                {
  779. X                case 'b': putchar('\b'); break;
  780. X                case 'c': nnl = 1; break;
  781. X                case 'e': putchar('\033'); break;
  782. X                case 'f': putchar('\f'); break;
  783. X                case 'n': putchar('\n'); break;
  784. X                case 'r': putchar('\r'); break;
  785. X                case 't': putchar('\t'); break;
  786. X                case 'v': putchar('\v'); break;
  787. X                case '\\': putchar('\\'); break;
  788. X                case '0': putchar(zstrtol(s,&s,8)); s--; break;
  789. X                default: putchar('\\'); putchar(*s); break;
  790. X                }
  791. X        else
  792. X            putchar(*s);
  793. X    return nnl;
  794. X}
  795. X
  796. X/* echo, print, pushln */
  797. X
  798. Xint bin_print(name,args,ops,func) /**/
  799. Xchar *name;char **args;char *ops;int func;
  800. X{
  801. Xint nnl = 0;
  802. X
  803. X    if (ops['z'])
  804. X        {
  805. X        permalloc();
  806. X        pushnode(bufstack,spacejoin(args));
  807. X        heapalloc();
  808. X        return 0;
  809. X        }
  810. X    if (ops['s'])
  811. X        {
  812. X        permalloc();
  813. X        addnode(histlist,join(args,HISTSPACE));
  814. X        addnode(lithistlist,join(args,' '));
  815. X        heapalloc();
  816. X        curhist++;
  817. X        return 0;
  818. X        }
  819. X    if (ops['R'])
  820. X        ops['r'] = 1;
  821. X    for (; *args; args++)
  822. X        {
  823. X        if (ops['D'])
  824. X            printdir(*args);
  825. X        else if (ops['P'])
  826. X            {
  827. X            int junk;
  828. X            fputs(putprompt(*args,&junk),stdout);
  829. X            }
  830. X        else if (ops['r'])
  831. X            fputs(*args,stdout);
  832. X        else
  833. X            nnl |= escputs(*args);
  834. X        if (args[1])
  835. X            putchar(ops['l'] ? '\n' : ops['0'] ? '\0' : ' ');
  836. X        }
  837. X    if (!(ops['n'] || nnl))
  838. X        putchar(ops['0'] ? '\0' : '\n');
  839. X    return 0;
  840. X}
  841. X
  842. Xint bin_dirs(name,argv,ops,func) /**/
  843. Xchar *name;char **argv;char *ops;int func;
  844. X{
  845. XLklist l;
  846. X
  847. X    if (ops['v'])
  848. X        {
  849. X        Lknode node;
  850. X        int t0 = 1;
  851. X
  852. X        printf("0\t");
  853. X        printdir(cwd);
  854. X        for (node = firstnode(dirstack); node; incnode(node))
  855. X            {
  856. X            printf("\n%d\t",t0++);
  857. X            printdir(getdata(node));
  858. X            }
  859. X        putchar('\n');
  860. X        return 0;
  861. X        }
  862. X    if (!*argv)
  863. X        {
  864. X        pdstack();
  865. X        return 0;
  866. X        }
  867. X    permalloc();
  868. X    l = newlist();
  869. X    if (!*argv)
  870. X        {
  871. X        heapalloc();
  872. X        return 0;
  873. X        }
  874. X    while (*argv)
  875. X        addnode(l,ztrdup(*argv++));
  876. X    freetable(dirstack,freestr);
  877. X    dirstack = l;
  878. X    heapalloc();
  879. X    return 0;
  880. X}
  881. X
  882. Xint bin_unalias(name,argv,ops,func) /**/
  883. Xchar *name;char **argv;char *ops;int func;
  884. X{
  885. Xint ret = 0;
  886. Xvptr dat;
  887. X
  888. X    while (*argv)
  889. X        {
  890. X        if (dat = remhnode(*argv++,aliastab))
  891. X            freeanode(dat);
  892. X        else
  893. X            ret = 1;
  894. X        }
  895. X    return ret;
  896. X}
  897. X
  898. X/* disable, unfunction, unhash */
  899. X
  900. Xint bin_unhash(name,argv,ops,func) /**/
  901. Xchar *name;char **argv;char *ops;int func;
  902. X{
  903. XCmdnam chn;
  904. X
  905. X    while (*argv)
  906. X        {
  907. X        if (!strncmp(*argv,"TRAP",4))
  908. X            unsettrap(getsignum(*argv+4));
  909. X        chn = zalloc(sizeof *chn);
  910. X        chn->type = DISABLED;
  911. X        addhnode(ztrdup(*argv++),chn,cmdnamtab,freecmdnam);
  912. X        }
  913. X    return 0;
  914. X}
  915. X
  916. Xint bin_unset(name,argv,ops,func) /**/
  917. Xchar *name;char **argv;char *ops;int func;
  918. X{
  919. Xint retval = 0;
  920. Xchar *s;
  921. X
  922. X    while (s = *argv++)
  923. X        if (gethnode(s,paramtab))
  924. X            unsetparam(s);
  925. X        else
  926. X            retval = 1;
  927. X    return retval;
  928. X}
  929. X
  930. Xstatic char *zbuf;
  931. X
  932. Xint zread() /**/
  933. X{
  934. Xchar cc;
  935. X
  936. X    if (zbuf)
  937. X        return *zbuf++;
  938. X    if (read(0,&cc,1) != 1)
  939. X        return EOF;
  940. X    return cc;
  941. X}
  942. X
  943. Xint bin_read(name,args,ops,func) /**/
  944. Xchar *name;char **args;char *ops;int func;
  945. X{
  946. Xchar *reply,*pmpt;
  947. Xint bsiz,c,gotnl = 0;
  948. Xchar *buf,*bptr;
  949. X
  950. X    attachtty((jobtab[thisjob].gleader) ? jobtab[thisjob].gleader : mypgrp);
  951. X    if (*args)
  952. X        reply = *args++;
  953. X    else
  954. X        reply = "REPLY";
  955. X    if (ops['z'])
  956. X        zbuf = (full(bufstack)) ? (char *) getnode(bufstack) : ztrdup("");
  957. X    else
  958. X        zbuf = NULL;
  959. X    if (isatty(0))
  960. X        {
  961. X        for (pmpt = reply; *pmpt && *pmpt != '?'; pmpt++);
  962. X        if (*pmpt++)
  963. X            {
  964. X            write(2,pmpt,strlen(pmpt));
  965. X            pmpt[-1] = '\0';
  966. X            }
  967. X        }
  968. X    while (*args)
  969. X        {
  970. X        buf = bptr = zalloc(bsiz = 64);
  971. Xredo:
  972. X        for(;;)
  973. X            {
  974. X            if (gotnl)
  975. X                break;
  976. X            c = zread();
  977. X            if (!ops['r'] && c == '\n' && bptr != buf && bptr[-1] == '\\')
  978. X                {
  979. X                bptr--;
  980. X                continue;
  981. X                }
  982. X            if (c == EOF || iblank(c))
  983. X                break;
  984. X            *bptr++ = c;
  985. X            if (bptr == buf+bsiz)
  986. X                {
  987. X                buf = realloc(buf,bsiz *= 2);
  988. X                bptr = buf+(bsiz/2);
  989. X                }
  990. X            }
  991. X        if (c == EOF)
  992. X            return 1;
  993. X        if (c == '\n')
  994. X            gotnl = 1;
  995. X        if (bptr == buf)
  996. X            goto redo;
  997. X        *bptr = '\0';
  998. X        setsparam(reply,buf);
  999. X        reply = *args++;
  1000. X        }
  1001. X    buf = bptr = zalloc(bsiz = 64);
  1002. X    if (!gotnl)
  1003. X        for (;;)
  1004. X            {
  1005. X            c = zread();
  1006. X            if (!ops['r'] && c == '\n' && bptr != buf && bptr[-1] == '\\')
  1007. X                {
  1008. X                bptr--;
  1009. X                continue;
  1010. X                }
  1011. X            if (c == EOF || c == '\n')
  1012. X                break;
  1013. X            *bptr++ = c;
  1014. X            if (bptr == buf+bsiz)
  1015. X                {
  1016. X                buf = realloc(buf,bsiz *= 2);
  1017. X                bptr = buf+(bsiz/2);
  1018. X                }
  1019. X            }
  1020. X    *bptr = '\0';
  1021. X    if (c == EOF)
  1022. X        return 1;
  1023. X    setsparam(reply,buf);
  1024. X    return 0;
  1025. X}
  1026. X
  1027. Xint bin_vared(name,args,ops,func) /**/
  1028. Xchar *name;char **args;char *ops;int func;
  1029. X{
  1030. Xchar *s,*t;
  1031. Xstruct param *pm;
  1032. X
  1033. X    if (!(s = getsparam(args[0])))
  1034. X        {
  1035. X        zerrnam(name,"no such variable: %s",args[0],0);
  1036. X        return 1;
  1037. X        }
  1038. X    permalloc();
  1039. X    pushnode(bufstack,ztrdup(s));
  1040. X    heapalloc();
  1041. X    t = zleread("> ",NULL,2);
  1042. X    if (!t || errflag)
  1043. X        return 1;
  1044. X    if (t[strlen(t)-1] == '\n')
  1045. X        t[strlen(t)-1] = '\0';
  1046. X    pm = gethnode(args[0],paramtab);
  1047. X    if (pmtype(pm) == PMFLAG_A)
  1048. X        setaparam(args[0],spacesplit(t));
  1049. X    else
  1050. X        setsparam(args[0],t);
  1051. X    return 0;
  1052. X}
  1053. X
  1054. X#define fset(X) (flags & X)
  1055. X
  1056. X/* execute a builtin handler function after parsing the arguments */
  1057. X
  1058. Xint execbin(args,cnode) /**/
  1059. XLklist args;Cmdnam cnode;
  1060. X{
  1061. Xstruct bincmd *b;
  1062. Xchar ops[128],*arg,*pp,*name,**argv,**oargv,*optstr;
  1063. Xint t0,flags,sense,argc = 0,op;
  1064. XLknode n;
  1065. X
  1066. X    auxdata = NULL;
  1067. X    auxlen = 0;
  1068. X    for (t0 = 0; t0 != 128; t0++)
  1069. X        ops[t0] = 0;
  1070. X    name = ugetnode(args);
  1071. X    b = builtins+cnode->u.binnum;
  1072. X
  1073. X/* the 'builtin' builtin is handled specially */
  1074. X
  1075. X    if (b->funcid == BIN_BUILTIN)
  1076. X        {
  1077. X        if (!(name = ugetnode(args)))
  1078. X            {
  1079. X            zerrnam("builtin","command name expected",NULL,0);
  1080. X            return 1;
  1081. X            }
  1082. X        for (t0 = 0, b = builtins; b->name; b++,t0++)
  1083. X            if (!strcmp(name,b->name))
  1084. X                break;
  1085. X        if (!b->name)
  1086. X            {
  1087. X            zerrnam("builtin","no such builtin: %s",name,0);
  1088. X            return 1;
  1089. X            }
  1090. X        }
  1091. X    flags = b->flags;
  1092. X    arg = ugetnode(args);
  1093. X    optstr = b->optstr;
  1094. X    if (flags & BINF_ECHOPTS && arg && strcmp(arg,"-n"))
  1095. X        optstr = NULL;
  1096. X    if (optstr)
  1097. X        while (arg &&
  1098. X                ((sense = *arg == '-') || fset(BINF_PLUSOPTS) && *arg == '+') &&
  1099. X                (fset(BINF_PLUSOPTS) || !atoi(arg)))
  1100. X            {
  1101. X            pp = arg;
  1102. X            if (arg[1] == '-')
  1103. X                arg++;
  1104. X            if (!arg[1])
  1105. X                {
  1106. X                ops['-'] = 1;
  1107. X                if (!sense)
  1108. X                    ops['+'] = 1;
  1109. X                }
  1110. X            else
  1111. X                ops['@'] = 1;
  1112. X            op = -1;
  1113. X            while (*++arg)
  1114. X                if (strchr(b->optstr,op = *arg))
  1115. X                    ops[*arg] = (sense) ? 1 : 2;
  1116. X                else
  1117. X                    break;
  1118. X            if (*arg)
  1119. X                {
  1120. X                zerr("bad option: %c",NULL,*arg);
  1121. X                return 1;
  1122. X                }
  1123. X            arg = ugetnode(args);
  1124. X            if (fset(BINF_SETOPTS) && op == 'o')
  1125. X                {
  1126. X                int c;
  1127. X                
  1128. X                if (!arg)
  1129. X                    prtopt();
  1130. X                else
  1131. X                    {
  1132. X                    c = optlookup(arg);
  1133. X                    if (c == -1)
  1134. X                        {
  1135. X                        zerr("bad option: %s",arg,0);
  1136. X                        return 1;
  1137. X                        }
  1138. X                    else
  1139. X                        {
  1140. X                        ops[c] = ops['o'];
  1141. X                        arg = ugetnode(args);
  1142. X                        }
  1143. X                    }
  1144. X                }
  1145. X            if ((fset(BINF_PRINTOPTS) && ops['R']) || ops['-'])
  1146. X                break;
  1147. X            if (fset(BINF_SETOPTS) && ops['A'])
  1148. X                {
  1149. X                auxdata = arg;
  1150. X                arg = ugetnode(args);
  1151. X                break;
  1152. X                }
  1153. X            if (fset(BINF_FCOPTS) && op == 'e')
  1154. X                {
  1155. X                auxdata = arg;
  1156. X                arg = ugetnode(args);
  1157. X                }
  1158. X            if (fset(BINF_TYPEOPT) && (op == 'L' || op == 'R' ||
  1159. X                    op == 'Z' || op == 'i') && arg && idigit(*arg))
  1160. X                {
  1161. X                auxlen = atoi(arg);
  1162. X                arg = ugetnode(args);
  1163. X                }
  1164. X            }
  1165. X    if (fset(BINF_R))
  1166. X        auxdata = "-";
  1167. X    if (pp = b->defopts)
  1168. X        while (*pp)
  1169. X            ops[*pp++] = 1;
  1170. X    if (arg)
  1171. X        {
  1172. X        argc = 1;
  1173. X        n = firstnode(args);
  1174. X        while (n)
  1175. X            argc++,incnode(n);
  1176. X        }
  1177. X    oargv = argv = (char **) ncalloc(sizeof(char **) * (argc+1));
  1178. X    if (*argv++ = arg)
  1179. X        while (*argv++ = ugetnode(args));
  1180. X    argv = oargv;
  1181. X    if (errflag)
  1182. X        return 1;
  1183. X    if (argc < b->minargs || (argc > b->maxargs && b->maxargs != -1)) {
  1184. X        zerrnam(name,(argc < b->minargs)
  1185. X            ? "not enough arguments" : "too many arguments",NULL,0);
  1186. X        return 1;
  1187. X    }
  1188. X    if (isset(XTRACE)) {
  1189. X        char **pp = argv;
  1190. X        fprintf(stderr,"%s%s",(prompt4) ? prompt4 : "",name);
  1191. X        while (*pp) fprintf(stderr," %s",*pp++);
  1192. X        fputc('\n',stderr);
  1193. X        fflush(stderr);
  1194. X    }
  1195. X    return (*(b->handlerfunc))(name,argv,ops,b->funcid);
  1196. X}
  1197. X
  1198. Xstruct asgment *getasg(s) /**/
  1199. Xchar *s;
  1200. X{
  1201. Xstatic struct asgment asg;
  1202. X
  1203. X    if (!s)
  1204. X        return NULL;
  1205. X    if (*s == '=')
  1206. X        {
  1207. X        zerr("bad assignment",NULL,0);
  1208. X        return NULL;
  1209. X        }
  1210. X    asg.name = s;
  1211. X    for (; *s && *s != '='; s++);
  1212. X    if (*s)
  1213. X        {
  1214. X        *s = '\0';
  1215. X        asg.value = s+1;
  1216. X        }
  1217. X    else
  1218. X        asg.value = NULL;
  1219. X    return &asg;
  1220. X}
  1221. X
  1222. X/* ., source */
  1223. X
  1224. Xint bin_dot(name,argv,ops,func) /**/
  1225. Xchar *name;char **argv;char *ops;int func;
  1226. X{
  1227. Xchar **old,*old0;
  1228. Xint ret;
  1229. Xchar buf[MAXPATHLEN];
  1230. Xchar *s,**t,*enam;
  1231. X
  1232. X    if (!*argv)
  1233. X        return 0;
  1234. X    old = pparams;
  1235. X    old0 = argzero;
  1236. X    permalloc();
  1237. X    pparams = arrdup(argv+1);
  1238. X    heapalloc();
  1239. X    enam = argzero = ztrdup(*argv);
  1240. X    errno = ENOENT;
  1241. X    ret = 1;
  1242. X    for (s = argzero; *s; s++)
  1243. X        if (*s == '/')
  1244. X            {
  1245. X            ret = source(argzero);
  1246. X            break;
  1247. X            }
  1248. X    if (!*s)
  1249. X        {
  1250. X        for (t = path; *t; t++)
  1251. X            if ((*t)[0] == '.' && !(*t)[1])
  1252. X                {
  1253. X                ret = source(argzero);
  1254. X                break;
  1255. X                }
  1256. X            else
  1257. X                {
  1258. X                sprintf(buf,"%s/%s",*t,argzero);
  1259. X                if (access(buf,F_OK) == 0)
  1260. X                    {
  1261. X                    ret = source(enam = buf);
  1262. X                    break;
  1263. X                    }
  1264. X                }
  1265. X        if (!*t && access(argzero,F_OK) == 0)
  1266. X            ret = source(enam = argzero);
  1267. X        }
  1268. X    freearray(pparams);
  1269. X    pparams = old;
  1270. X    if (ret)
  1271. X        zerrnam(name,"%e: %s",enam,errno);
  1272. X    free(argzero);
  1273. X    argzero = old0;
  1274. X    return ret;
  1275. X}
  1276. X
  1277. Xint bin_set(name,argv,ops,func) /**/
  1278. Xchar *name;char **argv;char *ops;int func;
  1279. X{
  1280. Xstruct option *opp;
  1281. Xchar **x;
  1282. X
  1283. X    if (((ops['+'] && ops['-']) || !ops['-']) && !ops['@'] && !*argv)
  1284. X        {
  1285. X        showflag = ~0;
  1286. X        showflag2 = ops['+'];
  1287. X        listhtable(paramtab,(HFunc) printparam);
  1288. X        }
  1289. X   for (opp = optns; opp->name; opp++)
  1290. X      if (ops[opp->id] == 1)
  1291. X         opts[opp->id] = OPT_SET;
  1292. X      else if (ops[opp->id] == 2)
  1293. X         opts[opp->id] = OPT_UNSET;
  1294. X    if (!*argv && !ops['-'])
  1295. X        return 0;
  1296. X    permalloc();
  1297. X    x = arrdup(argv);
  1298. X    heapalloc();
  1299. X    if (ops['A'])
  1300. X        setaparam(auxdata,x);
  1301. X    else
  1302. X        {
  1303. X        freearray(pparams);
  1304. X        permalloc();
  1305. X        pparams = x;
  1306. X        heapalloc();
  1307. X        }
  1308. X    return 0;
  1309. X}
  1310. X
  1311. X#define pttime(X) printf("%dm%ds",(X)/3600,(X)/60%60)
  1312. X
  1313. Xint bin_times(name,argv,ops,func) /**/
  1314. Xchar *name;char **argv;char *ops;int func;
  1315. X{
  1316. Xstruct tms buf;
  1317. X
  1318. X    if (times(&buf) == -1)
  1319. X        return 1;
  1320. X    pttime(buf.tms_utime);
  1321. X    putchar(' ');
  1322. X    pttime(buf.tms_stime);
  1323. X    putchar('\n');
  1324. X    pttime(buf.tms_cutime);
  1325. X    putchar(' ');
  1326. X    pttime(buf.tms_cstime);
  1327. X    putchar('\n');
  1328. X    return 0;
  1329. X}
  1330. X
  1331. Xint bin_getopts(name,argv,ops,func) /**/
  1332. Xchar *name;char **argv;char *ops;int func;
  1333. X{
  1334. Xchar *optstr = *argv++,*var = *argv++;
  1335. Xchar **args = (*argv) ? argv : pparams;
  1336. Xstatic int optcind = 1,quiet;
  1337. Xchar *str,optbuf[3],*opch = optbuf+1;
  1338. X
  1339. X    optbuf[0] = '+'; optbuf[1] = optbuf[2] = '\0';
  1340. X    if (optarg)
  1341. X        free(optarg);
  1342. X    optarg = ztrdup("");
  1343. X    setsparam(var,ztrdup(""));
  1344. X    if (*optstr == ':')
  1345. X        {
  1346. X        quiet = 1;
  1347. X        optstr++;
  1348. X        }
  1349. X    if (optind >= arrlen(args))
  1350. X        return 1;
  1351. X    str = args[optind];
  1352. X    if (*str != '+' && *str != '-' || optcind >= strlen(str) ||
  1353. X            !strcmp("--",str))
  1354. X        {
  1355. X        if (*str == '+' || *str == '-')
  1356. X            optind++;
  1357. X        optcind = 0;
  1358. X        return 1;
  1359. X        }
  1360. X    if (!optcind)
  1361. X        optcind = 1;
  1362. X    *opch = str[optcind++];
  1363. X    if (!args[optind][optcind])
  1364. X        {
  1365. X        optind++;
  1366. X        optcind = 0;
  1367. X        }
  1368. X    for (; *optstr; optstr++)
  1369. X        if (*opch == *optstr)
  1370. X            break;
  1371. X    if (!*optstr)
  1372. X        {
  1373. X        if (quiet)
  1374. X            {
  1375. X            optarg = ztrdup(opch);
  1376. X            setsparam(var,ztrdup("?"));
  1377. X            return 0;
  1378. X            }
  1379. X        zerr("bad option: %c",NULL,*opch);
  1380. X        return 1;
  1381. X        }
  1382. X    setsparam(var,ztrdup(opch-(*str == '+')));
  1383. X    if (optstr[1] == ':')
  1384. X        {
  1385. X        if (!args[optind])
  1386. X            {
  1387. X            if (quiet)
  1388. X                {
  1389. X                optarg = ztrdup(opch);
  1390. X                setsparam(var,ztrdup(":"));
  1391. X                return 0;
  1392. X                }
  1393. X            zerr("argument expected after %c option",NULL,*opch);
  1394. X            return 1;
  1395. X            }
  1396. X        free(optarg);
  1397. X        optarg = ztrdup(args[optind-1]+optcind);
  1398. X        optind++;
  1399. X        optcind = 0;
  1400. X        }
  1401. X    return 0;
  1402. X}
  1403. X
  1404. X/* get a signal number from a string */
  1405. X
  1406. Xint getsignum(s) /**/
  1407. Xchar *s;
  1408. X{
  1409. Xint x = atoi(s),t0;
  1410. X
  1411. X    if (idigit(*s) && x >= 0 && x < VSIGCOUNT)
  1412. X        return x;
  1413. X    for (t0 = 0; t0 != VSIGCOUNT; t0++)
  1414. X        if (!strcmp(s,sigs[t0]))
  1415. X            return t0;
  1416. X    return -1;
  1417. X}
  1418. X
  1419. Xint bin_trap(name,argv,ops,func) /**/
  1420. Xchar *name;char **argv;char *ops;int func;
  1421. X{
  1422. XList l;
  1423. Xchar *arg;
  1424. X
  1425. X    if (!*argv)
  1426. X        {
  1427. X        int t0;
  1428. X
  1429. X        for (t0 = 0; t0 != VSIGCOUNT; t0++)
  1430. X            if (sigtrapped[t0])
  1431. X                if (!sigfuncs[t0])
  1432. X                    printf("TRAP%s () {}\n",sigs[t0]);
  1433. X                else
  1434. X                    {
  1435. X                    char *s = gettext((vptr) sigfuncs[t0],1);
  1436. X                    printf("TRAP%s () {\n\t%s\n}\n",sigs[t0],s);
  1437. X                    free(s);
  1438. X                    }
  1439. X        return 0;
  1440. X        }
  1441. X    if (!strcmp(*argv,"-"))
  1442. X        {
  1443. X        int t0;
  1444. X
  1445. X        argv++;
  1446. X        if (*argv)
  1447. X            for (t0 = 0; t0 != VSIGCOUNT; t0++)
  1448. X                unsettrap(t0);
  1449. X        else
  1450. X            while (*argv)
  1451. X                unsettrap(getsignum(*argv++));
  1452. X        return 0;
  1453. X        }
  1454. X    arg = *argv++;
  1455. X    if (!*arg)
  1456. X        l = NULL;
  1457. X    else if (!(l = parselstring(arg)))
  1458. X        {
  1459. X        zerrnam(name,"couldn't parse trap command",NULL,0);
  1460. X        popheap();
  1461. X        return 1;
  1462. X        }
  1463. X    for (; *argv; argv++)
  1464. X        {
  1465. X        int sg = getsignum(*argv);
  1466. X        if (sg == -1)
  1467. X            {
  1468. X            zerrnam(name,"undefined signal: %s",*argv,0);
  1469. X            break;
  1470. X            }
  1471. X        settrap(sg,l);
  1472. X        }
  1473. X    if (l)
  1474. X        popheap();
  1475. X    return errflag;
  1476. X}
  1477. X
  1478. Xvoid printulimit(lim,hard) /**/
  1479. Xint lim;int hard;
  1480. X{
  1481. Xlong t0;
  1482. X
  1483. X#ifdef RLIM_INFINITY
  1484. X    t0 = (hard) ? limits[lim].rlim_max : limits[lim].rlim_cur;
  1485. X    switch (lim)
  1486. X        {
  1487. X        case RLIMIT_CPU: printf("cpu time (seconds)         "); break;
  1488. X        case RLIMIT_FSIZE: printf("file size (blocks)         "); t0 /= 512; break;
  1489. X        case RLIMIT_DATA: printf("data seg size (kbytes)     "); t0 /= 1024; break;
  1490. X        case RLIMIT_STACK: printf("stack size (kbytes)        "); t0 /= 1024; break;
  1491. X        case RLIMIT_CORE: printf("core file size (blocks)    "); t0 /= 512; break;
  1492. X#ifdef RLIMIT_RSS
  1493. X        case RLIMIT_RSS: printf("resident set size (kbytes) "); t0 /= 1024; break;
  1494. X#endif
  1495. X#ifdef RLIMIT_NOFILE
  1496. X        case RLIMIT_NOFILE: printf("file descriptors           "); break;
  1497. X#endif
  1498. X        }
  1499. X    printf("%ld\n",t0);
  1500. X#endif
  1501. X}
  1502. X
  1503. Xint bin_ulimit(name,argv,ops,func) /**/
  1504. Xchar *name;char **argv;char *ops;int func;
  1505. X{
  1506. Xint res,hard;
  1507. X
  1508. X#ifndef RLIM_INFINITY
  1509. X    zerrnam(name,"not available on this system",NULL,0);
  1510. X    return 1;
  1511. X#else
  1512. X    hard = ops['H'];
  1513. X    if (ops['a'] || !ops['@'])
  1514. X        res = -1;
  1515. X    else if (ops['t'])
  1516. X        res = RLIMIT_CPU;
  1517. X    else if (ops['f'])
  1518. X        res = RLIMIT_FSIZE;
  1519. X    else if (ops['d'])
  1520. X        res = RLIMIT_DATA;
  1521. X    else if (ops['s'])
  1522. X        res = RLIMIT_STACK;
  1523. X    else if (ops['c'])
  1524. X        res = RLIMIT_CORE;
  1525. X#ifdef RLIMIT_RSS
  1526. X    else if (ops['m'])
  1527. X        res = RLIMIT_RSS;
  1528. X#endif
  1529. X#ifdef RLIMIT_NOFILE
  1530. X    else if (ops['n'])
  1531. X        res = RLIMIT_NOFILE;
  1532. X#endif
  1533. X    else
  1534. X        {
  1535. X        zerrnam(name,"no such limit",NULL,0);
  1536. X        return 1;
  1537. X        }
  1538. X    if (res == -1)
  1539. X        if (*argv)
  1540. X            {
  1541. X            zerrnam(name,"no arguments required after -a",NULL,0);
  1542. X            return 1;
  1543. X            }
  1544. X        else
  1545. X            {
  1546. X            int t0;
  1547. X
  1548. X            for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
  1549. X                printulimit(t0,hard);
  1550. X            return 0;
  1551. X            }
  1552. X    if (!*argv)
  1553. X        printulimit(res,hard);
  1554. X    else if (strcmp(*argv,"unlimited"))
  1555. X        {
  1556. X        long t0;
  1557. X        
  1558. X        t0 = atol(*argv);
  1559. X        switch(res)
  1560. X            {
  1561. X            case RLIMIT_FSIZE: case RLIMIT_CORE: t0 *= 512; break;
  1562. X            case RLIMIT_DATA: case RLIMIT_STACK:
  1563. X#ifdef RLIMIT_RSS
  1564. X            case RLIMIT_RSS:
  1565. X#endif
  1566. X                t0 *= 1024; break;
  1567. X            }
  1568. X        if (hard)
  1569. X            {
  1570. X            if (t0 > limits[res].rlim_max && geteuid())
  1571. X                {
  1572. X                zerrnam(name,"can't raise hard limits",NULL,0);
  1573. X                return 1;
  1574. X                }
  1575. X            limits[res].rlim_max = t0;
  1576. X            }
  1577. X        else
  1578. X            {
  1579. X            if (t0 > limits[res].rlim_max)
  1580. X                {
  1581. X                if (geteuid())
  1582. X                    {
  1583. X                    zerrnam(name,"value exceeds hard limit",NULL,0);
  1584. X                    return 1;
  1585. X                    }
  1586. X                limits[res].rlim_max = limits[res].rlim_cur = t0;
  1587. X                }
  1588. X            else
  1589. X                limits[res].rlim_cur = t0;
  1590. X            }
  1591. X        }
  1592. X    else
  1593. X        {
  1594. X        if (hard)
  1595. X            {
  1596. X            if (geteuid())
  1597. X                {
  1598. X                zerrnam(name,"can't remove hard limits",NULL,0);
  1599. X                return 1;
  1600. X                }
  1601. X            limits[res].rlim_max = RLIM_INFINITY;
  1602. X            }
  1603. X        else
  1604. X            limits[res].rlim_cur = limits[res].rlim_max;
  1605. X        }
  1606. X    return 0;
  1607. X#endif
  1608. X}
  1609. X
  1610. Xint putraw(c) /**/
  1611. Xint c;
  1612. X{
  1613. X    putchar(c);
  1614. X    return 0;
  1615. X}
  1616. X
  1617. Xint bin_echotc(name,argv,ops,func) /**/
  1618. Xchar *name;char **argv;char *ops;int func;
  1619. X{
  1620. Xchar *s,buf[2048],*t,*u;
  1621. Xint num,argct,t0;
  1622. X
  1623. X    s = *argv++;
  1624. X    if (!termok)
  1625. X        return 1;
  1626. X    if ((num = tgetnum(s)) != -1)
  1627. X        {
  1628. X        printf("%d\n",num);
  1629. X        return 0;
  1630. X        }
  1631. X    u = buf;
  1632. X    t = tgetstr(s,&u);
  1633. X    if (!t || !*t)
  1634. X        {
  1635. X        zerrnam(name,"no such capability: %s",s,0);
  1636. X        return 1;
  1637. X        }
  1638. X    for (argct = 0, u = t; *u; u++)
  1639. X        if (*u == '%')
  1640. X            {
  1641. X            if (u++, (*u == 'd' || *u == '2' || *u == '3' || *u == '.' ||
  1642. X                    *u == '+'))
  1643. X                argct++;
  1644. X            }
  1645. X    if (arrlen(argv) != argct)
  1646. X        {
  1647. X        zerrnam(name,(arrlen(argv) < argct) ? "not enough arguments" :
  1648. X            "too many arguments",NULL,0);
  1649. X        return 1;
  1650. X        }
  1651. X    if (!argct)
  1652. X        tputs(t,1,putraw);
  1653. X    else
  1654. X        {
  1655. X        t0 = (argv[1]) ? atoi(argv[1]) : atoi(*argv);
  1656. X        tputs(tgoto(t,atoi(*argv),t0),t0,putraw);
  1657. X        }
  1658. X    return 0;
  1659. X}
  1660. X
  1661. Xint bin_pwd(name,argv,ops,func) /**/
  1662. Xchar *name;char **argv;char *ops;int func;
  1663. X{
  1664. X    printf("%s\n",cwd);
  1665. X    return 0;
  1666. X}
  1667. X
  1668. X#define TEST_END 0
  1669. X#define TEST_INPAR 1
  1670. X#define TEST_OUTPAR 2
  1671. X#define TEST_STR 3
  1672. X#define TEST_AND 4
  1673. X#define TEST_OR 5
  1674. X#define TEST_NOT 6
  1675. X
  1676. Xstatic char **tsp;
  1677. Xstatic int *tip;
  1678. X
  1679. Xint bin_test(name,argv,ops,func) /**/
  1680. Xchar *name;char **argv;char *ops;int func;
  1681. X{
  1682. Xchar **s;
  1683. Xint cnt,*arr,*ap;
  1684. XCond c;
  1685. X
  1686. X    if (func == BIN_BRACKET)
  1687. X        {
  1688. X        for (s = argv; *s; s++);
  1689. X        if (s == argv || strcmp(s[-1],"]"))
  1690. X            {
  1691. X            zerrnam(name,"']' expected",NULL,0);
  1692. X            return 1;
  1693. X            }
  1694. X        s[-1] = NULL;
  1695. X        }
  1696. X    for (s = argv, cnt = 0; *s; s++,cnt++);
  1697. X    ap = arr = alloc((cnt+1)*sizeof *arr);
  1698. X    for (s = argv; *s; s++,ap++)
  1699. X        if (!strcmp(*s,"("))
  1700. X            *ap = TEST_INPAR;
  1701. X        else if (!strcmp(*s,")"))
  1702. X            *ap = TEST_OUTPAR;
  1703. X        else if (!strcmp(*s,"-a"))
  1704. X            *ap = TEST_AND;
  1705. X        else if (!strcmp(*s,"-o"))
  1706. X            *ap = TEST_OR;
  1707. X        else if (!strcmp(*s,"!"))
  1708. X            *ap = TEST_NOT;
  1709. X        else
  1710. X            *ap = TEST_STR;
  1711. X    *ap = TEST_END;
  1712. X    tsp = argv;
  1713. X    tip = arr;
  1714. X    c = partest(0);
  1715. X    if (*tip != TEST_END || errflag)
  1716. X        {
  1717. X        zerrnam(name,"parse error",NULL,0);
  1718. X        return 1;
  1719. X        }
  1720. X    return (c) ? !evalcond(c) : 1;
  1721. X}
  1722. X
  1723. XCond partest(level) /**/
  1724. Xint level;
  1725. X{
  1726. XCond a,b;
  1727. X
  1728. X    switch (level)
  1729. X        {
  1730. X        case 0:
  1731. X            a = partest(1);
  1732. X            if (*tip == TEST_OR)
  1733. X                {
  1734. X                tip++,tsp++;
  1735. X                b = makecond();
  1736. X                b->left = a;
  1737. X                b->right = partest(0);
  1738. X                b->type = COND_OR;
  1739. X                return b;
  1740. X                }
  1741. X            return a;
  1742. X        case 1:
  1743. X            a = partest(2);
  1744. X            if (*tip == TEST_AND)
  1745. X                {
  1746. X                tip++,tsp++;
  1747. X                b = makecond();
  1748. X                b->left = a;
  1749. X                b->right = partest(1);
  1750. X                b->type = COND_AND;
  1751. X                return b;
  1752. X                }
  1753. X            return a;
  1754. X        case 2:
  1755. X            if (*tip == TEST_NOT)
  1756. X                {
  1757. X                tip++,tsp++;
  1758. X                b = makecond();
  1759. X                b->left = partest(2);
  1760. X                b->type = COND_NOT;
  1761. X                return b;
  1762. X                }
  1763. X        case 3:
  1764. X            if (*tip == TEST_INPAR)
  1765. X                {
  1766. X                tip++,tsp++;
  1767. X                b = partest(0);
  1768. X                if (*tip != TEST_OUTPAR)
  1769. X                    {
  1770. X                    zerrnam("test","parse error",NULL,0);
  1771. X                    return NULL;
  1772. X                    }
  1773. X                tip++,tsp++;
  1774. X                return b;
  1775. X                }
  1776. X            if (tip[0] != TEST_STR)
  1777. X                {
  1778. X                zerrnam("test","parse error",NULL,0);
  1779. X                return NULL;
  1780. X                }
  1781. X            else if (tip[1] != TEST_STR)
  1782. X                {
  1783. X                b = makecond();
  1784. X                if (!strcmp(*tsp,"-t"))
  1785. X                    {
  1786. X                    b->left = strdup("1");
  1787. X                    b->type = 't';
  1788. X                    }
  1789. X                else
  1790. X                    {
  1791. X                    b->left = tsp[0];
  1792. X                    b->type = 'n';
  1793. X                    }
  1794. X                tip++,tsp++;
  1795. X                return b;
  1796. X                }
  1797. X            else if (tip[2] != TEST_STR)
  1798. X                {
  1799. X                b = par_cond_double(tsp[0],tsp[1]);
  1800. X                tip += 2,tsp += 2;
  1801. X                return b;
  1802. X                }
  1803. X            else
  1804. X                {
  1805. X                b = par_cond_triple(tsp[0],tsp[1],tsp[2]);
  1806. X                tip += 3,tsp += 3;
  1807. X                return b;
  1808. X                }
  1809. X        }
  1810. X   return NULL;
  1811. X}
  1812. X
  1813. SHAR_EOF
  1814. echo 'File zsh2.1/src/builtin.c is complete' &&
  1815. chmod 0644 zsh2.1/src/builtin.c ||
  1816. echo 'restore of zsh2.1/src/builtin.c failed'
  1817. Wc_c="`wc -c < 'zsh2.1/src/builtin.c'`"
  1818. test 56254 -eq "$Wc_c" ||
  1819.     echo 'zsh2.1/src/builtin.c: original size 56254, current size' "$Wc_c"
  1820. rm -f _shar_wnt_.tmp
  1821. fi
  1822. # ============= zsh2.1/src/cond.c ==============
  1823. if test -f 'zsh2.1/src/cond.c' -a X"$1" != X"-c"; then
  1824.     echo 'x - skipping zsh2.1/src/cond.c (File already exists)'
  1825.     rm -f _shar_wnt_.tmp
  1826. else
  1827. > _shar_wnt_.tmp
  1828. echo 'x - extracting zsh2.1/src/cond.c (Text)'
  1829. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/src/cond.c' &&
  1830. X/*
  1831. X
  1832. X    cond.c - evaluate conditional expressions
  1833. X
  1834. X    This file is part of zsh, the Z shell.
  1835. X
  1836. X    zsh is free software; no one can prevent you from reading the source
  1837. X   code, or giving it to someone else.
  1838. X
  1839. X   This file is copyrighted under the GNU General Public License, which
  1840. X   can be found in the file called COPYING.
  1841. X
  1842. X   Copyright (C) 1990, 1991 Paul Falstad
  1843. X
  1844. X   zsh is distributed in the hope that it will be useful, but
  1845. X   WITHOUT ANY WARRANTY.  No author or distributor accepts
  1846. X   responsibility to anyone for the consequences of using it or for
  1847. X   whether it serves any particular purpose or works at all, unless he
  1848. X   says so in writing.  Refer to the GNU General Public License
  1849. X   for full details.
  1850. X
  1851. X   Everyone is granted permission to copy, modify and redistribute
  1852. X   zsh, but only under the conditions described in the GNU General Public
  1853. X   License.   A copy of this license is supposed to have been given to you
  1854. X   along with zsh so you can know your rights and responsibilities.
  1855. X   It should be in a file named COPYING.
  1856. X
  1857. X   Among other things, the copyright notice and this notice must be
  1858. X   preserved on all copies.
  1859. X
  1860. X*/
  1861. X
  1862. X#include "zsh.h"
  1863. X
  1864. Xint evalcond(c) /**/
  1865. XCond c;
  1866. X{
  1867. Xstruct stat *st;
  1868. X
  1869. X    switch (c->type)
  1870. X        {
  1871. X        case COND_NOT: return !evalcond(c->left);
  1872. X        case COND_AND: return evalcond(c->left) && evalcond(c->right);
  1873. X        case COND_OR: return evalcond(c->left) || evalcond(c->right);
  1874. X        }
  1875. X    singsub((char **) &c->left);
  1876. X    untokenize(c->left);
  1877. X    if (c->right)
  1878. X        {
  1879. X        singsub((char **) &c->right);
  1880. X        if (c->type != COND_STREQ && c->type != COND_STRNEQ)
  1881. X            untokenize(c->right);
  1882. X        }
  1883. X    switch (c->type)
  1884. X        {
  1885. X        case COND_STREQ: return matchpat(c->left,c->right);
  1886. X        case COND_STRNEQ: return !matchpat(c->left,c->right);
  1887. X        case COND_STRLT: return strcmp(c->left,c->right) < 0;
  1888. X        case COND_STRGTR: return strcmp(c->left,c->right) > 0;
  1889. X        case 'a': return(doaccess(c->left,F_OK));
  1890. X        case 'b': return(S_ISBLK(dostat(c->left)));
  1891. X        case 'c': return(S_ISCHR(dostat(c->left)));
  1892. X        case 'd': return(S_ISDIR(dostat(c->left)));
  1893. X        case 'f': return(S_ISREG(dostat(c->left)));
  1894. X        case 'g': return(!!(dostat(c->left) & S_ISGID));
  1895. X        case 'k': return(!!(dostat(c->left) & S_ISVTX));
  1896. X        case 'n': return(!!strlen(c->left));
  1897. X        case 'o': return(optison(c->left));
  1898. X        case 'p': return(S_ISFIFO(dostat(c->left)));
  1899. X        case 'r': return(doaccess(c->left,R_OK));
  1900. X        case 's': return((st = getstat(c->left)) && !!(st->st_size));
  1901. X        case 'S': return(S_ISSOCK(dostat(c->left)));
  1902. X        case 'u': return(!!(dostat(c->left) & S_ISUID));
  1903. X        case 'w': return(doaccess(c->left,W_OK));
  1904. X        case 'x': return(doaccess(c->left,X_OK));
  1905. X        case 'z': return(!strlen(c->left));
  1906. X        case 'L': return(S_ISLNK(dolstat(c->left)));
  1907. X        case 'O': return((st = getstat(c->left)) && st->st_uid == geteuid());
  1908. X        case 'G': return((st = getstat(c->left)) && st->st_gid == getegid());
  1909. X        case 't': return isatty(matheval(c->left));
  1910. X        case COND_EQ: return matheval(c->left) == matheval(c->right);
  1911. X        case COND_NE: return matheval(c->left) != matheval(c->right);
  1912. X        case COND_LT: return matheval(c->left) < matheval(c->right);
  1913. X        case COND_GT: return matheval(c->left) > matheval(c->right);
  1914. X        case COND_LE: return matheval(c->left) <= matheval(c->right);
  1915. X        case COND_GE: return matheval(c->left) >= matheval(c->right);
  1916. X        case COND_NT: case COND_OT:
  1917. X            {
  1918. X            time_t a;
  1919. X            if (!(st = getstat(c->left)))
  1920. X                return 0;
  1921. X            a = st->st_mtime;
  1922. X            if (!(st = getstat(c->right)))
  1923. X                return 0;
  1924. X            return (c->type == COND_NT) ? a > st->st_mtime : a < st->st_mtime;
  1925. X            }
  1926. X        case COND_EF:
  1927. X            {
  1928. X            dev_t d;
  1929. X            ino_t i;
  1930. X
  1931. X            if (!(st = getstat(c->left)))
  1932. X                return 0;
  1933. X            d = st->st_dev;
  1934. X            i = st->st_ino;
  1935. X            if (!(st = getstat(c->right)))
  1936. X                return 0;
  1937. X            return d == st->st_dev && i == st->st_ino;
  1938. X            }
  1939. X        default: zerr("bad cond structure",NULL,0);
  1940. X        }
  1941. X    return 0;
  1942. X}
  1943. X
  1944. Xint doaccess(s,c) /**/
  1945. Xchar *s;int c;
  1946. X{
  1947. X    return !access(s,c);
  1948. X}
  1949. X
  1950. Xstatic struct stat st;
  1951. X
  1952. Xstruct stat *getstat(s) /**/
  1953. Xchar *s;
  1954. X{
  1955. X    if (!strncmp(s,"/dev/fd/",8))
  1956. X        {
  1957. X        if (fstat(atoi(s+8),&st))
  1958. X            return NULL;
  1959. X        }
  1960. X    else if (stat(s,&st))
  1961. X        return NULL;
  1962. X    return &st;
  1963. X}
  1964. X
  1965. Xunsigned short dostat(s) /**/
  1966. Xchar *s;
  1967. X{
  1968. Xstruct stat *st;
  1969. X
  1970. X    if (!(st = getstat(s)))
  1971. X        return 0;
  1972. X    return st->st_mode;
  1973. X}
  1974. X
  1975. X/* pem@aaii.oz; needed since dostat now uses "stat" */
  1976. X
  1977. Xunsigned short dolstat(s) /**/
  1978. Xchar *s;
  1979. X{
  1980. X    if (lstat(s, &st) < 0)
  1981. X        return 0;
  1982. X    return st.st_mode;
  1983. X}
  1984. X
  1985. Xint optison(s) /**/
  1986. Xchar *s;
  1987. X{
  1988. Xint i;
  1989. X
  1990. X    if (strlen(s) == 1)
  1991. X        return opts[*s];
  1992. X    if ((i = optlookup(s)) != -1)
  1993. X        return opts[i];
  1994. X    zerr("no such option: %s",s,0);
  1995. X    return 0;
  1996. X}
  1997. X
  1998. SHAR_EOF
  1999. chmod 0644 zsh2.1/src/cond.c ||
  2000. echo 'restore of zsh2.1/src/cond.c failed'
  2001. Wc_c="`wc -c < 'zsh2.1/src/cond.c'`"
  2002. test 4485 -eq "$Wc_c" ||
  2003.     echo 'zsh2.1/src/cond.c: original size 4485, current size' "$Wc_c"
  2004. rm -f _shar_wnt_.tmp
  2005. fi
  2006. # ============= zsh2.1/src/exec.c ==============
  2007. if test -f 'zsh2.1/src/exec.c' -a X"$1" != X"-c"; then
  2008.     echo 'x - skipping zsh2.1/src/exec.c (File already exists)'
  2009.     rm -f _shar_wnt_.tmp
  2010. else
  2011. > _shar_wnt_.tmp
  2012. echo 'x - extracting zsh2.1/src/exec.c (Text)'
  2013. sed 's/^X//' << 'SHAR_EOF' > 'zsh2.1/src/exec.c' &&
  2014. X/*
  2015. X
  2016. X    exec.c - command execution
  2017. X
  2018. X    This file is part of zsh, the Z shell.
  2019. X
  2020. X    zsh is free software; no one can prevent you from reading the source
  2021. X   code, or giving it to someone else.
  2022. X
  2023. X   This file is copyrighted under the GNU General Public License, which
  2024. X   can be found in the file called COPYING.
  2025. X
  2026. X   Copyright (C) 1990, 1991 Paul Falstad
  2027. X
  2028. X   zsh is distributed in the hope that it will be useful, but
  2029. X   WITHOUT ANY WARRANTY.  No author or distributor accepts
  2030. X   responsibility to anyone for the consequences of using it or for
  2031. X   whether it serves any particular purpose or works at all, unless he
  2032. X   says so in writing.  Refer to the GNU General Public License
  2033. X   for full details.
  2034. X
  2035. X   Everyone is granted permission to copy, modify and redistribute
  2036. X   zsh, but only under the conditions described in the GNU General Public
  2037. X   License.   A copy of this license is supposed to have been given to you
  2038. X   along with zsh so you can know your rights and responsibilities.
  2039. X   It should be in a file named COPYING.
  2040. X
  2041. X   Among other things, the copyright notice and this notice must be
  2042. X   preserved on all copies.
  2043. X
  2044. X*/
  2045. X
  2046. X#include "zsh.h"
  2047. X#include <sys/errno.h>
  2048. X#ifdef __hpux
  2049. X#include <ndir.h>
  2050. X#else
  2051. X#include <sys/dir.h>
  2052. X#endif
  2053. X
  2054. X#define execerr() { if (forked) exit(1); \
  2055. X    closemnodes(mfds); errflag = 1; return; }
  2056. X
  2057. X/* parse list in a string */
  2058. X
  2059. XList parselstring(s) /**/
  2060. Xchar *s;
  2061. X{
  2062. XList l;
  2063. X
  2064. X    hungets(s);
  2065. X    strinbeg();
  2066. X    pushheap();
  2067. X    if (!(l = parse_list()))
  2068. X        {
  2069. X        strinend();
  2070. X        hflush();
  2071. X        popheap();
  2072. X        return NULL;
  2073. X        }
  2074. X    strinend();
  2075. X    return l;
  2076. X}
  2077. X
  2078. X/* execute a string */
  2079. X
  2080. Xvoid execstring(s) /**/
  2081. Xchar *s;
  2082. X{
  2083. XList l;
  2084. X
  2085. X    if (l = parselstring(s))
  2086. X        {
  2087. X        execlist(l);
  2088. X        popheap();
  2089. X        }
  2090. X}
  2091. X
  2092. X/* duplicate a list and run it */
  2093. X
  2094. Xvoid newrunlist(l) /**/
  2095. XList l;
  2096. X{
  2097. X    List a = (List) dupstruct(l); runlist(a);
  2098. X}
  2099. X
  2100. X/* fork and set limits */
  2101. X
  2102. Xint phork() /**/
  2103. X{
  2104. Xint pid = fork(),t0;
  2105. X
  2106. X    if (pid == -1)
  2107. X        {
  2108. X        zerr("fork failed: %e",NULL,errno);
  2109. X        return -1;
  2110. X        }
  2111. X#ifdef RLIM_INFINITY
  2112. X    if (!pid)
  2113. X        for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
  2114. X            setrlimit(t0,limits+t0);
  2115. X#endif
  2116. X    return pid;
  2117. X}
  2118. X
  2119. X/* execute a current shell command */
  2120. X
  2121. Xint execcursh(cmd) /**/
  2122. XCmd cmd;
  2123. X{
  2124. X    runlist(cmd->u.list);
  2125. X    cmd->u.list = NULL;
  2126. X    return lastval;
  2127. X}
  2128. X
  2129. X/* execve after handling $_ and #! */
  2130. X
  2131. X#define POUNDBANGLIMIT 64
  2132. X
  2133. Xvoid zexecve(pth,argv,ee,b1,b2) /**/
  2134. Xchar *pth;char **argv;int *ee;char *b1;char *b2;
  2135. X{
  2136. Xint eno;
  2137. Xchar buf[MAXPATHLEN*2];
  2138. Xchar **eep;
  2139. X
  2140. X    for (eep = environ; *eep; eep++)
  2141. X        if (**eep == '_' && (*eep)[1] == '=')
  2142. X            break;
  2143. X    buf[0] = '_';
  2144. X    buf[1] = '=';
  2145. X    if (*pth == '/')
  2146. X        strcpy(buf+2,pth);
  2147. X    else
  2148. X        sprintf(buf+2,"%s/%s",cwd,pth);
  2149. X    if (!*eep)
  2150. X        eep[1] = NULL;
  2151. X    *eep = buf;
  2152. X    execve(pth,argv,environ);
  2153. X    if ((eno = errno) == ENOEXEC)
  2154. X        {
  2155. X        char buf[POUNDBANGLIMIT+1],*ptr,*ptr2,*argv0;
  2156. X        int fd,ct,t0;
  2157. X
  2158. X        if ((fd = open(pth,O_RDONLY)) >= 0)
  2159. X            {
  2160. X            argv0 = *argv;
  2161. X            *argv = pth;
  2162. X            ct = read(fd,buf,POUNDBANGLIMIT);
  2163. X            close(fd);
  2164. X            if (ct > 0)
  2165. X                {
  2166. X                if (buf[0] == '#')
  2167. X                    if (buf[1] == '!')
  2168. X                        {
  2169. X                        for (t0 = 0; t0 != ct; t0++)
  2170. X                            if (buf[t0] == '\n')
  2171. X                                buf[t0] = '\0';
  2172. X                        buf[POUNDBANGLIMIT] = '\0';
  2173. X                        for (ptr = buf+2; *ptr && *ptr == ' '; ptr++);
  2174. X                        for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++);
  2175. X                        if (*ptr)
  2176. X                            {
  2177. X                            *ptr = '\0';
  2178. X                            argv[-2] = ptr2;
  2179. X                            argv[-1] = ptr+1;
  2180. X                            execve(ptr2,argv-2,environ);
  2181. X                            }
  2182. X                        else
  2183. X                            {
  2184. X                            argv[-1] = ptr2;
  2185. X                            execve(ptr2,argv-1,environ);
  2186. X                            }
  2187. X                        }
  2188. X                    else
  2189. X                        {
  2190. X                        argv[-1] = "sh";
  2191. X                        execve("/bin/sh",argv-1,environ);
  2192. X                        }
  2193. X                else
  2194. X                    {
  2195. X                    for (t0 = 0; t0 != ct; t0++)
  2196. X                        if (!buf[t0])
  2197. X                            break;
  2198. X                    if (t0 == ct)
  2199. X                        {
  2200. X                        argv[-1] = "sh";
  2201. X                        execve("/bin/sh",argv-1,environ);
  2202. X                        }
  2203. X                    }
  2204. X                }
  2205. X            else
  2206. X                eno = errno;
  2207. X            *argv = argv0;
  2208. X            }
  2209. X        else
  2210. X            eno = errno;
  2211. X        }
  2212. X    if (ee && eno != ENOENT)
  2213. X        {
  2214. X        *ee = eno;
  2215. X        strcpy(b1,b2);
  2216. X        }
  2217. X}
  2218. X
  2219. X#define MAXCMDLEN (MAXPATHLEN*4)
  2220. X
  2221. X/* execute an external command */
  2222. X
  2223. Xvoid execute(args,dash) /**/
  2224. XLklist args;int dash;
  2225. X{
  2226. Xchar **argv,*arg0;
  2227. Xchar *z,*s,buf[MAXCMDLEN],buf2[MAXCMDLEN];
  2228. XCmdnam cn;
  2229. Xint tl,ee = 0;
  2230. X
  2231. X    if (!full(args)) {
  2232. X        zerr("no command");
  2233. X        _exit(1);
  2234. X    }
  2235. X    cn = (Cmdnam) gethnode(peekfirst(args),cmdnamtab);
  2236. X    if (cn && cn->type == DISABLED)
  2237. X        cn = NULL;
  2238. X    if (s = zgetenv("STTY"))
  2239. X        zyztem("stty",s);
  2240. X    arg0 = peekfirst(args);
  2241. X    if (z = zgetenv("ARGV0"))
  2242. X        {
  2243. X        setdata(firstnode(args),ztrdup(z));
  2244. X        delenv(z-6);
  2245. X        }
  2246. X    else if (dash)
  2247. X        {
  2248. X        sprintf(buf2,"-%s",arg0);
  2249. X        setdata(firstnode(args),ztrdup(buf2));
  2250. X        }
  2251. X    argv = makecline(args);
  2252. X    fixsigs();
  2253. X    if (cn && ISEXCMD(cn->type))
  2254. X        {
  2255. X        if (cn->type == EXCMD_POSTDOT)
  2256. X            zexecve(arg0,argv,&ee,buf2,buf);
  2257. X        zexecve(cn->u.nam,argv,&ee,buf2,buf);
  2258. X        }
  2259. X    for (s = arg0; *s; s++)
  2260. X        if (*s == '/')
  2261. X            {
  2262. X            zexecve(arg0,argv,NULL,NULL,NULL);
  2263. X            if (arg0 == s || unset(PATHDIRS))
  2264. X                {
  2265. X                zerr("%e: %s",arg0,errno);
  2266. X                _exit(1);
  2267. X                }
  2268. X            break;
  2269. X            }
  2270. X    for (; *path; path++)
  2271. X        if ((*path)[0] == '.' && !(*path)[1])
  2272. X            zexecve(arg0,argv,&ee,buf2,buf);
  2273. X        else
  2274. X            {
  2275. X            tl = strlen(*path);
  2276. X            strcpy(buf,*path);
  2277. X            buf[tl] = '/';
  2278. X            if (strlen(arg0)+strlen(buf)+1 >= MAXCMDLEN)
  2279. X                {
  2280. X                zerr("command too long: %s",arg0,0);
  2281. X                _exit(1);
  2282. X                }
  2283. X            strcpy(buf+tl+1,arg0);
  2284. X            zexecve(buf,argv,&ee,buf2,buf);
  2285. X            }
  2286. X    if (ee)
  2287. X        {
  2288. X        zerr("%e: %s",arg0,ee);
  2289. X        _exit(1);
  2290. X        }
  2291. X    zerr("command not found: %s",arg0,0);
  2292. X    _exit(1);
  2293. X}
  2294. X
  2295. X#define try(X) { if (!access(X,X_OK)) return ztrdup(X); }
  2296. X
  2297. X/* get the pathname of a command */
  2298. X
  2299. Xchar *findcmd(arg0) /**/
  2300. Xchar *arg0;
  2301. X{
  2302. Xchar *s,buf[MAXPATHLEN];
  2303. Xint tl;
  2304. Xstruct cmdnam *cn = (Cmdnam) gethnode(arg0,cmdnamtab);
  2305. Xchar **pp = path;
  2306. X
  2307. X    if (cn && cn->type == DISABLED)
  2308. X        cn = NULL;
  2309. X    if (cn && ISEXCMD(cn->type))
  2310. X        {
  2311. X        if (cn->type == EXCMD_POSTDOT)
  2312. X            {
  2313. X            strcpy(buf,"./");
  2314. X            strcat(buf,arg0);
  2315. X            try(buf);
  2316. X            }
  2317. X        try(cn->u.nam);
  2318. X        }
  2319. X    for (s = arg0; *s; s++)
  2320. X        if (*s == '/')
  2321. X            {
  2322. X            try(arg0);
  2323. X            if (s == arg0 || unset(PATHDIRS))
  2324. X                goto failed;
  2325. X            break;
  2326. X            }
  2327. X    for (; *pp; pp++)
  2328. X        if (**pp == '.')
  2329. X            {
  2330. X            strcpy(buf,"./");
  2331. X            strcat(buf,arg0);
  2332. X            try(buf);
  2333. X            }
  2334. X        else
  2335. X            {
  2336. X            tl = strlen(*pp);
  2337. X            strcpy(buf,*pp);
  2338. X            buf[tl] = '/';
  2339. X            strcpy(buf+tl+1,arg0);
  2340. X            try(buf);
  2341. X            }
  2342. Xfailed:
  2343. X    return NULL;
  2344. X}
  2345. X
  2346. Xvoid execlist(list) /**/
  2347. XList list;
  2348. X{
  2349. X    if (breaks)
  2350. X        return;
  2351. X    simplifyright(list);
  2352. X    switch(list->type)
  2353. X        {
  2354. X        case SYNC:
  2355. X        case ASYNC:
  2356. X            execlist2(list->left,list->type,!list->right);
  2357. X            if (sigtrapped[SIGDEBUG])
  2358. X                dotrap(SIGDEBUG);
  2359. X            if (sigtrapped[SIGERR] && lastval)
  2360. X                dotrap(SIGERR);
  2361. X            if (list->right && !retflag)
  2362. X                execlist(list->right);
  2363. X            break;
  2364. X        }
  2365. X}
  2366. X
  2367. Xvoid execlist2(list,type,last1) /**/
  2368. XSublist list;int type;int last1;
  2369. X{
  2370. X    switch(list->type)
  2371. X        {
  2372. X        case END:
  2373. X            execpline(list,type,last1);
  2374. X            break;
  2375. X        case ORNEXT:
  2376. X            if (!execpline(list,SYNC,0))
  2377. X                execlist2(list->right,type,last1);
  2378. X            break;
  2379. X        case ANDNEXT:
  2380. X            if (execpline(list,SYNC,0))
  2381. X                execlist2(list->right,type,last1);
  2382. X            break;
  2383. X        }
  2384. X}
  2385. X
  2386. Xint execpline(l,how,last1) /**/
  2387. XSublist l;int how;int last1;
  2388. X{
  2389. Xint ipipe[2],opipe[2];
  2390. X
  2391. X    ipipe[0] = ipipe[1] = opipe[0] = opipe[1] = 0;
  2392. SHAR_EOF
  2393. true || echo 'restore of zsh2.1/src/exec.c failed'
  2394. fi
  2395. echo 'End of zsh2.1.0 part 5'
  2396. echo 'File zsh2.1/src/exec.c is continued in part 6'
  2397. echo 6 > _shar_seq_.tmp
  2398. exit 0
  2399.  
  2400. exit 0 # Just in case...
  2401. -- 
  2402. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  2403. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  2404. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  2405. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  2406.